package com.biz.service.api;

import com.biz.model.Hmodel.TbaseDetail;
import com.biz.model.Hmodel.basic.*;
import com.biz.model.Hmodel.goods.baseStandard;
import com.biz.model.Hmodel.goods.goodsBrand;
import com.biz.model.Hmodel.goods.goodsUnit;
import com.biz.model.Pmodel.basic.Base90Detail;
import com.biz.service.basic.UserServiceI;
import com.framework.dao.hdao.BaseDaoI;
import com.framework.dao.mdao.DaoSupport;
import com.framework.utils.DateUtil;
import com.framework.utils.StringUtil;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/***
 * lzq
 */
@Service("apiInterfaceService")
public class ApiInterfaceServiceImpl implements ApiInterfaceServiceI{

	@Resource(name = "daoSupport")
	private DaoSupport dao;

	@Autowired
	private BaseDaoI<TwxGoodsGroup> wxgoodsGroup;
	@Autowired
	private BaseDaoI<Ttag> tagDao;

	@Autowired
	private BaseDaoI<baseStandard> standDao;
	@Autowired
	private BaseDaoI<Twxgoods> wxgoodsDao;
	@Autowired
	private BaseDaoI<TBaseBrand> basebrandao;

	@Autowired
	private BaseDaoI<Tbase90DetailLog>  baseDetailLogDao;
	@Autowired
	private BaseDaoI<goodsUnit> unitsDao;

	@Autowired
	private BaseDaoI<goodsBrand> brandDao;
	@Autowired
	private BaseDaoI<TwxgoodsProperty> wxgoodsPropertyDao;

	@Autowired
	private BaseDaoI<TwxgoodsStock> wxgoodsStockDao;

	@Autowired
	private BaseDaoI<TgoodsTag> goodsTagDao;

	@Autowired
	private BaseDaoI<Tpics> picsDao;
	@Autowired
	private BaseDaoI<TbaseDetail> baseDetailDao;

	@Autowired
	private UserServiceI userService;

	/*@Resource(name = "wxTemplateService")
	private WxTemplateServiceI wxTemplateService;*/




	@Override
	public Map<String, Object> updateUserBalance(Map<String, Object> map) throws Exception {
		JSONObject jSONObject = new JSONObject();
		List<Map<String,String>> checkMap=(List<Map<String, String>>) dao.findForList("BaseUserDao.getUserDetail90ByWx", map);//获取流水记录防止重复调用
		Map<String,Object> user=(Map<String, Object>) dao.findForObject("BaseUserDao.getUserBalanceByOpenId", map);//获取用户id和剩余久零券
		Map<String,Object> userMain=(Map<String, Object>) dao.findForObject("BaseUserDao.getUserByOpenId", map);//获取用户id和剩余久零券

		Date expiryTime=null;
            map.put("sorts",99);

		String source=map.get("source").toString();
		String state=map.get("state").toString();
		Double amount=Double.valueOf(map.get("balance_90").toString());

		boolean isBalance=false;
		boolean isBalanceOK=true;
		if(user!=null)
		{
			String userBalance=user.get("balance_90").toString();
			double balance_90=Double.parseDouble(userBalance);

			double balance_90Main=Double.parseDouble(userMain.get("balance_90")+"");
			if("1".equals(state))//如果是要支出久零券的，校验是否够
			{
				isBalance=balance_90>=amount;
				map.put("point90Now",0);
				if((Math.abs(balance_90Main-balance_90)>0.01))
				{
					isBalanceOK=false;
				}

				if("9".equals(source)||"10".equals(source))//当撤回的时候，需要撤回总额
				{
					map.put("balance_90Total",map.get("balance_90"));
				}else
				{
					map.put("balance_90Total",0);
				}

			}else{
				map.put("point90Now",amount);
				isBalance=true;

				if(!"5".equals(source))//当退款的时候，不增加总额
				{
					map.put("balance_90Total",map.get("balance_90"));
				}else
				{
					map.put("balance_90Total",0);
				}

			/*	//获取90券的时候读取商户信息获得过期时间
				int expiryDateType=2;

				Date grantTime=new Date();*/
			/*	try{
					grantTime=getGrantTime(map);
				}
				catch (Exception e)
				{
					e.getMessage();
				}*/
			/*	String expiryTimeString=getExpiryTime(grantTime,expiryDateType);
				if(!StringUtil.isNullOrEmpty(expiryTimeString))
				{
					SimpleDateFormat sdfTime = new SimpleDateFormat(
							"yyyy-MM-dd HH:mm:ss");
					expiryTime=sdfTime.parse(expiryTimeString);
				}
				else
				{
					SimpleDateFormat sdfTime = new SimpleDateFormat(
							"yyyy-MM-dd HH:mm:ss");
					expiryTime=sdfTime.parse(DateUtil.laterDate(365));
				}
			}*/
		}
		SimpleDateFormat sdfTime = new SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss");
		expiryTime=sdfTime.parse(DateUtil.laterDate(-3650));
		map.put("expiryTime",expiryTime);

		if(!isBalanceOK)
		{
			jSONObject.put("flag", "4");
			jSONObject.put("msg", "操作失败，发券记录与用户余额不匹配");
			dao.update("BaseUserDao.updateUserForBalance90Wrong",map);
			return jSONObject;
		}
		if(checkMap!=null&&checkMap.size()>0)
		{
			jSONObject.put("flag", "3");
			jSONObject.put("msg", "操作失败，重复调用");
			return jSONObject;
		}else if(!isBalance)
		{
			jSONObject.put("flag", "2");
			jSONObject.put("msg", "操作失败，余额不足");
			return jSONObject;
		}
		String mainId= map.get("order_code")+"";
			if("3".equals(source)){
				int res=doOperBalanceForConsume(user,map,mainId);//当为消费久零券的时候，进行久零券的消券操作
				if(res<0)//消费处理失败，直接返回失败
				{
					jSONObject.put("flag", "2");
					jSONObject.put("msg", "操作失败，没有加券记录用于消费");
					throw new Exception("操作失败，没有加券记录用于消费");
				}
			}
            if("5".equals(source)){
				TbaseDetail detail =baseDetailDao.getByHql("from TbaseDetail where source=3 and isdel=0 and sourceId='"+map.get("order_code")+"'");
				int res=doOperBalanceForRefundsNew(user,map,mainId);//当为退款退券的时候，单独处理
                if(res<0)//消费处理失败，直接返回失败
                {
                    jSONObject.put("flag", "2");
                    jSONObject.put("msg", "操作失败，没有加券记录用于消费");
					throw new Exception("操作失败，没有加券记录用于消费");
                }
				map.put("point90Now",res);
            }
            if("9".equals(source)||"10".equals(source)) {    //单独处理撤回
				TbaseDetail detail =baseDetailDao.getById(TbaseDetail.class,map.get("order_code")+"");
				jSONObject = doCancalNew(map.get("order_code") + "", user, source,mainId);
                if(!"0".equals(jSONObject.get("flag")))
                {throw new Exception("");}
            }
           dao.update("BaseUserDao.operBalance90ByWx", map);


			map.put("userId",user.get("id"));
			if(!map.containsKey("applyUserId")){
				map.put("applyUserId",null);
			}
			dao.save("BaseUserDao.saveDetail90ByWx", map);//插入流水记录
				jSONObject.put("flag", "0");
				jSONObject.put("msg", "操作成功");

		}
		return jSONObject;
	}


	private String getExpiryTime(Date grantTime,int expiryDateType) {
		String dateString="";
		switch (expiryDateType)
		{
			case 1:dateString=laterDate(grantTime,90);break;
			case 2:dateString=laterDate(grantTime,365);break;
			case 3:dateString=laterDate(grantTime,1095);break;
			default:dateString=laterDate(grantTime,365);break;
		}
		return  dateString;
	}
	public  String laterDate(Date grantTime,int days) {
		DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date temp_date = null;
		try {
			Calendar c = Calendar.getInstance();
			c.setTime(grantTime);
			c.add(Calendar.DATE, days);
			temp_date = c.getTime();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return format.format(temp_date);
	}
	private int doOperBalanceForRefundsNew(Map<String, Object> user, Map<String, Object> map,String id) throws Exception {

			List<Map<String,Object>> list= (List<Map<String,Object>>) dao.findForList("BaseUserDao.getLogByOrderId",map);
		if(list.size()<=0)
		{throw  new Exception("没有找到对应的消费记录");}
		Integer amount=Integer.valueOf(map.get("balance_90").toString());
		for(Map<String,Object> log:list)
		{
			Integer point=Integer.valueOf(log.get("point90")+"");
			TbaseDetail detail =baseDetailDao.getById(TbaseDetail.class,log.get("sourceId")+"");
			Tbase90DetailLog detailLog=new Tbase90DetailLog();
			detailLog.setType(2);
			detailLog.setOrderId(id);
			detailLog.setSourceId(detail.getId());
			if(point>=amount)
			{
				detail.setPoint90Now(detail.getPoint90Now()+amount);
				detailLog.setPoint90(amount);
				amount=0;

			}else
			{
				detail.setPoint90Now(detail.getPoint90Now()+point);
				amount=amount-point;
				detailLog.setPoint90(point);
			}
			baseDetailDao.update(detail);
			baseDetailLogDao.save(detailLog);
			if(amount<=0)
			{break;}
		}
		return amount;

	}
	private int doOperBalanceForRefunds(Map<String, Object> user, Map<String, Object> map,String id) {


        String hql=StringUtil.formateString("from TbaseDetail t where t.openId='{0}'  and t.state=0 and t.isdel=0 and t.inOuts=1 order by t.expireTime desc",map.get("open_id")+"");
        List<TbaseDetail> baseDetailList=baseDetailDao.find(hql);
        Integer amount=Integer.valueOf(map.get("balance_90").toString());
        if(baseDetailList.size()<=0)//如果没有找到加券记录，返回-1
        {return -1;}
        else//否则对记录按照顺序循环操作
        {
            for(TbaseDetail detail:baseDetailList)
            {
                if(amount<=0)
                {break;}

                if(detail.getPoint90Now().intValue()==detail.getPoint90().intValue())
                {
                    //没有被消费过的充值记录，不操作
                }
                else if((detail.getPoint90Now()+amount)>detail.getPoint90().intValue())
                {//从被消费过的充值记录开始，补全
					Tbase90DetailLog log=new Tbase90DetailLog();
					log.setType(2);
					log.setOrderId(id);
					log.setSourceId(detail.getId());
					log.setPoint90(detail.getPoint90()-detail.getPoint90Now());
                    amount=amount-(detail.getPoint90()-detail.getPoint90Now());
                    detail.setPoint90Now(detail.getPoint90());
                    baseDetailDao.update(detail);
					baseDetailLogDao.save(log);
                }
                else
                {
					Tbase90DetailLog log=new Tbase90DetailLog();
					log.setType(2);
					log.setOrderId(id);
					log.setSourceId(detail.getId());
					log.setPoint90(amount);
                    detail.setPoint90Now(detail.getPoint90Now()+amount);
                    amount=0;
                    baseDetailDao.update(detail);
					baseDetailLogDao.save(log);
                    break;
                }
            }
            if(amount<=0)
            {return 0;}
            else
            {return amount;}
        }
    }

    private int doOperBalanceForConsume(Map<String, Object> user, Map<String, Object> map,String id) {

		String hql=StringUtil.formateString("from TbaseDetail t where t.openId='{0}' and t.point90Now>0 and t.state=0 and t.isdel=0 and t.inOuts=1 order by t.sorts asc, t.expireTime asc",map.get("open_id")+"");
		List<TbaseDetail> baseDetailList=baseDetailDao.find(hql);

		Integer amount=Integer.valueOf(map.get("balance_90").toString());
		if(baseDetailList.size()<=0)//如果没有找到加券记录，返回-1
		{return -1;}
		else//否则对记录按照顺序循环操作
		{
			for(TbaseDetail detail:baseDetailList)
			{
				if(amount<=0)
				{break;}
				Tbase90DetailLog log=new Tbase90DetailLog();
				log.setType(0);
				log.setOrderId(id);
				log.setSourceId(detail.getId());
 				if(detail.getPoint90Now().intValue()>=amount)
				{
					log.setPoint90(amount);
					detail.setPoint90Now(detail.getPoint90Now()-amount);
					baseDetailDao.update(detail);
					baseDetailLogDao.save(log);
					break;
				}
				else
				{
					log.setPoint90(detail.getPoint90Now());
					amount=amount-detail.getPoint90Now();
					detail.setPoint90Now(0);
					baseDetailDao.update(detail);
					baseDetailLogDao.save(log);
				}
			}
		}
			return 1;
	}

    private JSONObject doCancalNew(String order_code, Map<String, Object> user, String source, String id) throws Exception {
        JSONObject jSONObject = new JSONObject();
        String userBalance=user.get("balance_90").toString();
        int balance_90=Integer.parseInt(userBalance);
        /**以下进行预处理，判断是否够退券**/
        TbaseDetail td=baseDetailDao.getById(TbaseDetail.class,order_code);
        if ((td!=null)&&(td.getIsdel()==0))
        {
            if(td.getPoint90()>balance_90)
            {
                jSONObject.put("flag", "2");
                jSONObject.put("msg", "操作失败，余额不足");
                return jSONObject;
            }

            Map<String,Object> map=new HashMap<>();
            map.put("balance_90",td.getPoint90());
            map.put("open_id",td.getOpenId());

            /**以下处理对用户进行退券**/
          //  int res=(int) dao.update("BaseUserDao.cancalBalance90ByWx", map);

            if(td.getPoint90Now()>=td.getPoint90())//当该笔记录的余额没有消费的时候，直接扣除,完成退券
            {
				Tbase90DetailLog log=new Tbase90DetailLog();
				log.setType(1);
				log.setOrderId(id);
				log.setSourceId(td.getId());
				log.setPoint90(td.getPoint90());
                td.setPoint90Now(td.getPoint90Now()-td.getPoint90());
				baseDetailLogDao.save(log);

            }else{
                int amount=td.getPoint90()-td.getPoint90Now();//当余额不足的时候，先扣该笔记录，然后从其他记录扣券
				Tbase90DetailLog log=new Tbase90DetailLog();
				log.setType(1);
				log.setOrderId(id);
				log.setSourceId(td.getId());
				log.setPoint90(td.getPoint90Now());
                td.setPoint90Now(0);
				baseDetailLogDao.save(log);

                String hql=StringUtil.formateString("from TbaseDetail t where t.openId='{0}' and t.point90Now>0 and t.state=0 and t.isdel=0 and t.inOuts=1 and t.ticketType='{1}' order by t.expireTime asc",map.get("open_id")+"",map.get("ticketType")+"");
                List<TbaseDetail> baseDetailList=baseDetailDao.find(hql);
                if(baseDetailList.size()<=0)//如果没有找到加券记录，返回-1
                {  jSONObject.put("flag", "2");
                    jSONObject.put("msg", "操作失败，余额不足");
                }
                else//否则对记录按照顺序循环操作
                {
                    for(TbaseDetail detail:baseDetailList)
                    {
                        if(amount<=0)
                        {break;}
						 log=new Tbase90DetailLog();
						log.setType(1);
						log.setOrderId(id);
						log.setSourceId(detail.getId());
                        if(detail.getPoint90Now()>=amount&&!detail.getId().equals(td.getId()))
                        {
							log.setPoint90(amount);
                            detail.setPoint90Now(detail.getPoint90Now()-amount);
                            baseDetailDao.update(detail);
							baseDetailLogDao.save(log);
                            break;
                        }
                        else if(!detail.getId().equals(td.getId()))
                        {
							log.setPoint90(detail.getPoint90Now());
                            amount=amount-detail.getPoint90Now();
                            detail.setPoint90Now(0);
                            baseDetailDao.update(detail);
							baseDetailLogDao.save(log);
                        }
                    }
                }
            }
                td.setIsdel(1);
                td.setCancelTime(new Date());
                baseDetailDao.update(td);
                jSONObject.put("flag", "0");
                jSONObject.put("msg", "操作成功");

        }else
        {
            jSONObject.put("flag", "1");
            jSONObject.put("msg", "操作失败,找不到对应的发券记录");
            return jSONObject;
        }
        return jSONObject;
    }



	@Override
	public List<Base90Detail> selectOrtherBalanceIn(Map<String, Object> map) throws Exception {
		return (List<Base90Detail>) dao.findForList("BaseUserDao.selectOrtherBalanceIn", map);
	}

	@Override
	public int int_sum(Map<String, Object> map) throws Exception {
		Object o = dao.findForObject("BaseUserDao.int_sum", map);
		return (int) (o != null ? o : 0);
	}

	@Override
	public List<Base90Detail> selectOrtherBalanceOut(Map<String, Object> map) throws Exception {
		return (List<Base90Detail>) dao.findForList("BaseUserDao.selectOrtherBalanceOut", map);
	}

	@Override
	public int out_sum(Map<String, Object> map) throws Exception {
		Object o = dao.findForObject("BaseUserDao.out_sum", map);
		return (int) (o != null ? o : 0);
	}
}
